﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BigPang.Render;

namespace BigPang
{
    public partial class EditorForm : Form
    {
        Map mMap;
        string[] imgStrs = new string[3];
        bool isTileBoxMouseDown = false;

        Bitmap mSourceBitmap;

        Bitmap mSelectBitmap;

        Point mTileBoxStart;
        Point mTileBoxEnd;

        Point mTilePosition;

        int layerId = 0;

        public enum EditType
        {
            Set,
            Clear,

            CanPass,
            NotPass,
        }

        public EditType EditorType { get; set; }

        public EditorForm()
        {
            InitializeComponent();

            imgStrs[0] = "./ResData/TILE_1.png";
            imgStrs[1] = "./ResData/TILE_2.png";
            imgStrs[2] = "./ResData/TILE_3.png";

            //mMap = new Map(imgStrs, 20, 16);

            //mMap.Init();

            EditorType = EditType.Set;


        }

        private void gameCanvas1_OnDrawFrame(object sender, EventArgs e)
        {
            Canvas canvas = sender as Canvas;

            try
            {
                mMap.OnRender(canvas.Graph);
            }
            catch { }

            if (mSelectBitmap != null)
                canvas.Graph.DrawImageUnscaled(mSelectBitmap, mTilePosition);
        }

        private void EditorForm_Load(object sender, EventArgs e)
        {
            //mMap = Map.LoadFile("./test.xml");
            List<EditType> typeList = new List<EditType>();
            typeList.Add(EditType.Set);
            typeList.Add(EditType.Clear);
            typeList.Add(EditType.CanPass);
            typeList.Add(EditType.NotPass);

            this.editTypeBindingSource.DataSource = typeList;

            ChangeLayer(0);
        }

        void ChangeLayer(int id)
        {
            tileBox.ImageLocation = imgStrs[id];
            mSourceBitmap = Bitmap.FromFile(imgStrs[id]) as Bitmap;
            layerId = id;
        }

        private void tileBox_MouseDown(object sender, MouseEventArgs e)
        {
            tileBox.Capture = true;

            isTileBoxMouseDown = true;

            mTileBoxStart = e.Location;
            mTileBoxStart.X /= Map.TileSize;
            mTileBoxStart.Y /= Map.TileSize;

            mTileBoxEnd = e.Location;
            mTileBoxEnd.X /= Map.TileSize;
            mTileBoxEnd.Y /= Map.TileSize;

            tileBox.Invalidate();
        }

        private void tileBox_MouseUp(object sender, MouseEventArgs e)
        {
            mTileBoxEnd = e.Location;
            mTileBoxEnd.X /= Map.TileSize;
            mTileBoxEnd.Y /= Map.TileSize;

            tileBox.Invalidate();
            Size s = new Size((mTileBoxEnd.X - mTileBoxStart.X + 1) * Map.TileSize, (mTileBoxEnd.Y - mTileBoxStart.Y + 1) * Map.TileSize);

            mSelectBitmap = new Bitmap(s.Width, s.Height);
            Graphics g = Graphics.FromImage(mSelectBitmap);
            g.DrawImage(mSourceBitmap, new Rectangle(0, 0, s.Width, s.Height), new Rectangle(mTileBoxStart.X * Map.TileSize, mTileBoxStart.Y * Map.TileSize, s.Width, s.Height), GraphicsUnit.Pixel);
            isTileBoxMouseDown = false;

            tileBox.Capture = false;
        }

        private void tileBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (isTileBoxMouseDown)
            {
                mTileBoxEnd = e.Location;
                mTileBoxEnd.X /= Map.TileSize;
                mTileBoxEnd.Y /= Map.TileSize;

                tileBox.Invalidate();
            }
        }

        private void tileBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Green)), new Rectangle(mTileBoxStart.X * Map.TileSize, mTileBoxStart.Y * Map.TileSize, (mTileBoxEnd.X+1 - mTileBoxStart.X) * Map.TileSize, (mTileBoxEnd.Y+1-mTileBoxStart.Y) * Map.TileSize));
        }

        private void gameCanvas1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void gameCanvas1_MouseMove(object sender, MouseEventArgs e)
        {
            mTilePosition = e.Location;

            mTilePosition.X /= Map.TileSize;
            mTilePosition.X *= Map.TileSize;

            mTilePosition.Y /= Map.TileSize;
            mTilePosition.Y *= Map.TileSize;

            if ((e.Button & MouseButtons.Left) != MouseButtons.None )
            {
                switch (EditorType)
                {
                    case EditType.Set:
                        setTiles(e.Location);
                        break;
                    case EditType.Clear:
                        clearTiles(e.Location);
                        break;
                    case EditType.CanPass:
                        setPass(e.Location, true);
                        break;
                    case EditType.NotPass:
                        setPass(e.Location, false);
                        break;
                }
            }
        }

        void setPass(Point p, bool canPass)
        {
            p.X /= Map.TileSize;
            p.Y /= Map.TileSize;

            int xLength = mSourceBitmap.Width / Map.TileSize;

            for (int i = p.X; i <= mTileBoxEnd.X - mTileBoxStart.X + p.X; i++)
            {
                for (int j = p.Y; j <= mTileBoxEnd.Y - mTileBoxStart.Y + p.Y; j++)
                {
                    mMap.SetPass(i, j, canPass);
                }
            }
        }

        void clearTiles(Point p)
        {
            p.X /= Map.TileSize;
            p.Y /= Map.TileSize;

            int xLength = mSourceBitmap.Width / Map.TileSize;

            for (int i = p.X; i <= mTileBoxEnd.X - mTileBoxStart.X + p.X; i++)
            {
                for (int j = p.Y; j <= mTileBoxEnd.Y - mTileBoxStart.Y + p.Y; j++)
                {
                    mMap.SetTile(layerId, i, j, -1);
                }
            }
        }

        void setTiles( Point p )
        {
            p.X /= Map.TileSize;
            p.Y /= Map.TileSize;

            int xLength = mSourceBitmap.Width / Map.TileSize;

            for (int i = p.X; i <= mTileBoxEnd.X - mTileBoxStart.X + p.X; i++)
            {
                for (int j = p.Y; j <= mTileBoxEnd.Y - mTileBoxStart.Y + p.Y; j++)
                {
                    mMap.SetTile(layerId, i, j, i - p.X + mTileBoxStart.X + (j - p.Y + mTileBoxStart.Y) * xLength);
                }
            }
        }

        private void gameCanvas1_MouseClick(object sender, MouseEventArgs e)
        {
            switch (EditorType)
            {
                case EditType.Set:
                    setTiles(e.Location);
                    break;
                case EditType.Clear:
                    clearTiles(e.Location);
                    break;
                case EditType.CanPass:
                    setPass(e.Location, true);
                    break;
                case EditType.NotPass:
                    setPass(e.Location, false);
                    break;
            }
        }

        private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mMap.SaveFile("./test.xml");
        }

        private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mMap = new Map(imgStrs, 20, 16);
            mMap.Init();
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            ChangeLayer((int)this.numericUpDown1.Value);
        }

        private void comboBox1_ValueMemberChanged(object sender, EventArgs e)
        {
            
        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            if (comboBox1.SelectedValue == null)
                return;

            EditorType = (EditType)comboBox1.SelectedValue;
        }
    }
}
